<?php
/*
 * class OAuth
 */
//require_once('../adapter/http/curl.adp.php');
class OAuth  {
    var $appKey=NULL;
    var $appSecret=NULL;
    var $consumer_key=NULL;
    var $consumer_secret=NULL;
    var $oauth_token=NULL;//可站点缓存变量
    var $oauth_token_secret=NULL;//可站点缓存变量
    
    var $oauth_token_authorize=NULL;
    var $oauth_verifier=NULL;
    
    var $oauth_token_access=NULL;//用于普通的API请求的access_token 微博系统中，
				//OAuth的Access token不会过期，只有用户手工撤销授权或新浪收回您的app访问权限access token才会失效。
    var $oauth_token_secret_access=NULL;
    
    var $require_token_url=NULL;
    
    //var $urlList=array();
    var $oauth_version ='1.0';
    var $signMethod='';
    var $signMethodSupport=array('HMAC-SHA1'=>array('hash_hmac',array('sha1','%s','%s',TRUE)));//%s为填充数据，分别为data,key
    var $http=NULL;
    var $isWeb=TRUE;//是否是web方式的oAuth，如果是需要制定oauth_callback参数；
    
    var $params=array();
    
    
    function OAuth($args){
	$this->appKey=$args['appKey'];
	$this->consumer_key=$this->appKey;
	
	$this->consumer_secret=$this->appSecret=$args['appSecret'];
	
	isset($args['signMethod'])&&$this->signMethod=$args['signMethod'];
	$this->oauth_version=isset($args['oauth_version'])?$args['oauth_version']:'1.0';
	$this->isWeb=isset($args['isWeb'])?$args['isWeb']:TRUE;
	$this->defaultCallbackUrl=isset($args['defaultCallbackUrl'])?$args['defaultCallbackUrl']:NULL;    
	$this->http=APP::ADP('http');
	$this->params=array('oauth_consumer_key'=>$this->consumer_key,
			    'oauth_signature_method'=>$this->signMethod,
			    'oauth_version'=>$this->oauth_version
			    );
    }
    
    function _preBaseParams(){
	$this->params['oauth_timestamp']=time();
	$this->params['oauth_nonce']=/*md5(time());*/rand(1000,99999999);
    }
    //function  get
    // wap page xml json oob
    //oauth_callback:URL or json/xml or 表示桌面应用
    function getAuthorizeURL($display='page',$oauth_callback=NULL){
	$params=array('oauth_token'=>isset($this->oauth_token)?$this->oauth_token:$_SESSION['oauth_token']);
	$url='http://api.t.sina.com.cn/oauth/authorize';
	switch($display){
	    case 'wap':
	    case 'wap1.2':
	    case 'wap2.0':
		$params['display']=$display;
		break;
	    case 'popup':
		$params['display']=$display;
		break;
	    case 'json':
	    case 'xml':
		$params['display']='page';
		$params['oauth_callback']=$display;
	    case 'page':
	    default:
		if($oauth_callback!=NULL) $params['oauth_callback']=$oauth_callback;    
	}
	//var_dump($params);
	return $url.'?'. http_build_query($params);
    }
    function setAccessToken($access_token,$oauth_token_secret_access=NULL){
	$_SESSION['oauth_token_access']=$access_token;
	$this->oauth_token_access=$_SESSION['oauth_token_access'];
	if($oauth_token_secret_access!=NULL){
	    $_SESSION['oauth_token_secret_access']=$oauth_token_secret_access;
	    $this->oauth_token_secret_access=$_SESSION['oauth_token_secret_access'];
	}
    }
    
    function getAccessToken(){
	if(isset($_SESSION['oauth_token_access'])&&isset($_SESSION['oauth_token_secret_access'])){
	    $this->oauth_token_access=$_SESSION['oauth_token_access'];
	    $this->oauth_token_secret_access=$_SESSION['oauth_token_secret_access'];
	    return;
	}
	
	$url='http://api.t.sina.com.cn/oauth/access_token';
	$this->_preBaseParams();
	$params=$this->params;
	$params['oauth_token']=$this->oauth_token_authorize;
	$params['oauth_verifier']=$this->oauth_verifier;
	if($this->oauth_token==NULL){
	    $this->oauth_token=$_SESSION['oauth_token'];
	}
	if($this->oauth_token_secret==NULL){
	    $this->oauth_token_secret=$_SESSION['oauth_token_secret'];
	}
	$params['oauth_signature']=$this->_sign($this->signMethodSupport[$this->signMethod],
						'post',
						$url,
						$params,
						$this->appSecret.'&'.$_SESSION['oauth_token_secret']
						);
	//var_dump($params);
	$this->http->init($url);
	$this->http->set(array('post'=>$params));
	$ret=$this->http->request('post',TRUE);
	//var_dump($ret);
	if($ret['errno']==0){
	    $arr2=$this->_str2Array($ret['data']);
	    if(isset($arr2['oauth_token'])){
		$this->oauth_token_access=$arr2['oauth_token'];
		$_SESSION['oauth_token_access']=$this->oauth_token_access;
	    }
	    if(isset($arr2['oauth_token_secret'])){
		$this->oauth_token_secret_access=$arr2['oauth_token_secret'];
		$_SESSION['oauth_token_secret_access']=$this->oauth_token_secret_access;
	    }
	    if(isset($arr2['user_id'])){
		$_SESSION['user_id']=$arr2['user_id'];
	    }
	}
    }
    
    function getAuthorizeCallBackOAuth($display='page'){
	switch($display){
	    case 'page':
		//from url get query;
		$this->oauth_token_authorize=V('g:oauth_token');
		$this->oauth_verifier=V('g:oauth_verifier');
		if($this->oauth_token_authorize&&$this->oauth_verifier) return TRUE;
		return FALSE;
		break;
	    case 'wap':
	    case 'wap1.2':
	    case 'wap2.0':
		break;
	    case 'json':
		break;
	    case 'xml':
		break;
	}
    }
    
    function  getRequestToken(){
	unset($_SESSION['oauth_token_secret']);
	unset($_SESSION['oauth_token']);	
	$url=$this->require_token_url;
	$this->_preBaseParams();
	$params=$this->params;
	if($this->defaultCallbackUrl!=NULL){
	    $params['oauth_callback']=$this->defaultCallbackUrl;
	}
	//var_dump($params);
	$params['oauth_signature']=$this->_sign($this->signMethodSupport[$this->signMethod],
						'post',
						$url,
						$params,
						$this->appSecret.'&');
	//var_dump($params);
	//$params['oauth_signature']=base64_encode($params['oauth_signature']);
	
	$this->http->init($url);
	$this->http->set(array('post'=>$params));
	$ret=$this->http->request('post',TRUE);
	//var_dump($ret);
	if($ret['errno']==0){
	    
	    $arr2=$this->_str2Array($ret['data']);
	    if(isset($arr2['oauth_token'])){
		$this->oauth_token=$arr2['oauth_token'];
	    }
	    if(isset($arr2['oauth_token_secret'])){
		$this->oauth_token_secret=$arr2['oauth_token_secret'];
	    }
	    $_SESSION['oauth_token']=$this->oauth_token;
	    $_SESSION['oauth_token_secret']=$this->oauth_token_secret;
	}
	
    }
    
    function _del_at($arr,$fileKeyArr){
	$ret=array();
	foreach($arr as $k=>$v){
	    if(in_array($k,$fileKeyArr)&&$v{0}=='@'){
		$ret[$k]= file_get_contents(ltrim( $v , '@' ));
	    }
	    else{
		$ret[$k]=$v;
	    }
	}
	return $ret;
    }
    
    function _sign($fun,$method='get',$url='',$args=array(),$key=NULL,$fileKeyArr=array('pic','image','img')){
	if(!empty($args)){
	    ksort($args);
	    $args=$this->_del_at($args,$fileKeyArr);
	    //uksort($params, 'strcmp'); 
	}
	//var_dump($args);
	$baseString= strtoupper($method).'&'.urlencode($url).'&'.join('%26',$this->_arrKeyValCombine($args));
	
	//var_dump($baseString);
	if(is_array($fun)){
	    $fun_name=array_shift($fun);
	    $arg_add=array($baseString,$key);
	    $i=0;
	    $fun_arg=array();
	    $funarg=array_shift($fun);
	    
	    foreach($funarg as $arg){
		
		if($arg==='%s'){
		    $arg=$arg_add[$i++];
		}
		
		$fun_arg[]=$arg;
	    }
	    
	    return base64_encode(call_user_func_array($fun_name,$fun_arg));
	}
	else{
	    return base64_encode(call_user_func_array($fun,array($this->appSecret.'&',$baseString)));    
	}
	
    }
    
    function _arrKeyValCombine($arr){
	$_ret=array();
	foreach($arr as $key=>$val){
	    $_ret[]=urlencode($key).'%3D'.urlencode($val);
	}
	return $_ret;
    }
    
    function _str2Array($data){
	    $arr=explode('&',$data);
	    $arr2=array();
	    foreach($arr as $val){
		$tmp=explode('=',$val);
		$arr2[$tmp[0]]=$tmp[1];
	    }
	    return $arr2;
    }
    
    function _urlencodeMulti($array){
	if(is_array($array)){
	    $keys=array_keys($array);
	    $values=array_values($array);
	    $keys=array_batch($keys,'urlencode_rfc3986');
	    $values=array_batch($values,'urlencode_rfc3986',FALSE,'/^@/');
	    return array_combine($keys,$values);    
	}
	elseif(is_scalar($array)){
	    return urlencode_rfc3986($array);
	}
	
	
    }
    
    function oauthRequire($url,$params,$secret,$method='post',$format='json',$multi=FALSE,$fileKeyArr=array('pic','image','img')){
	$this->_preBaseParams();
	$params=array_merge($this->params,$params);
	$params=$this->_urlencodeMulti($params);
	$params['oauth_signature']=$this->_urlencodeMulti($this->_sign($this->signMethodSupport[$this->signMethod],
					$method,
					$url,
					$params,
					$secret,
					$fileKeyArr
					));//这个无需编码
	
	
	$this->http->init($url);
	$this->http->set(array($method=>$params),$multi,$fileKeyArr);
	$ret=$this->http->request($method);
	if($ret['errno']==0){
	    switch($format){
		case 'json':
		    return json_decode($ret['data'],TRUE);
		    break;
		case 'xml':
		    return;
		    break;
	    }
	    
	}
	else{
	    return NULL;
	}
    }
    
    
}


//$oa=new OAuth($args);
//$oa->getRequestToken();
//var_dump($oa);
?>